﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

using Styx.WoWInternals.DBC;
using Styx.WoWInternals.WoWObjects;
using Styx.WoWInternals;
using Styx.Common;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.Pathing;
using Styx;
using System.Diagnostics;
using System.Threading;
using System.IO;
using Styx.CommonBot;
using System.Windows.Forms;
using Styx.CommonBot.Inventory;
using System.Runtime.InteropServices;

namespace KingWoW
{
    class FrostMageCombatClass : KingWoWAbstractBaseClass
    {

        private static string Name = "KingWoW FrostMage'";

        #region CONSTANT AND VARIABLES

        //START OF CONSTANTS ==============================
        private string[] StealBuffs = { "Innervate", "Hand of Freedom", "Hand of Protection", "Regrowth", "Rejuvenation", "Lifebloom", "Renew", 
                                      "Hand of Salvation", "Power Infusion", "Power Word: Shield", "Arcane Power", "Hot Streak!",  /*"Avenging Wrath",*/ 
                                      "Elemental Mastery", "Nature's Swiftness", "Divine Plea", "Divine Favor", "Icy Veins", "Ice Barrier", "Holy Shield", 
                                      "Divine Aegis", "Bloodlust", "Time Warp", "Brain Freeze"};
        private static bool IsCRPaused = false;
        private const bool LOGGING = true;
        private const bool DEBUG = false;
        private const bool TRACE = false;
        private static KingWoWUtility utils = null;
        private Movement movement = null;
        private ExtraUtils extra = null;
        WoWUnit target = null;
        private WoWUnit tank = null;
        private WoWUnit off_tank = null;
        private WoWUnit lastTank = null;
        private WoWUnit lastOffTank = null;
        private bool SoloBotType = false;
        private string BaseBot = "unknown";
        private DateTime nextTimeRuneOfPowerAllowed;
        private DateTime nextTimeFrostBombAllowed;
        private TalentManager talents = null;

        private WoWUnit blizzardCandidateTarget = null;
        WoWUnit IceNovaCandidateTarget = null;
        WoWUnit CometStormCandidateTarget = null;

        private Random rnd = new Random();
        private int RANDOM_TIME = 0;

        private const string DEBUG_LABEL = "DEBUG";
        private const string TRACE_LABEL = "TRACE";
        private const string TANK_CHANGE = "TANK CHANGED";
        private const string OFF_TANK_CHANGE = "OFF_TANK CHANGED";
        private const string FACING = "FACING";

        //START OF SPELLS AND AURAS ==============================
        private const string DRINK = "Drink";
        private const string FOOD = "Food";

        private const string FROSTFIRE_BOLT = "Frostfire Bolt";
        private const string FROST_NOVA = "Frost Nova";
        private const string FIRE_BLAST = "Fire Blast";
        private const string BLINK = "Blink";
        private const string COUNTERSPELL = "Counterspell";
        private const string SUMMON_WATER_ELEMENTAL = "Summon Water Elemental";
        private const string FROSTBOLT = "Frostbolt";
        private const string POLYMORPH = "Polymorph";
        private const string ICE_LANCE = "Ice Lance";
        private const string FINGER_OF_FROST = "Fingers of Frost";
        private const string ICE_BLOCK = "Ice Block";
        private const string CONE_OF_COLD = "Cone of Cold";
        private const string REMOVE_CURSE = "Remove Curse";
        private const string SLOW_FALL = "Slow Fall";
        private const string ICY_VEINS = "Icy Veins";
        private const string CONJURE_REFRESHMENT = "Conjure Refreshment";
        private const string EVOCATION = "Evocation";
        private const string MIRROR_IMAGE = "Mirror Image";
        private const string BLIZZARD = "Blizzard";
        private const string INVISIBILITY = "Invisibility";
        private const string ARCANE_BRILLANCE = "Arcane Brilliance";
        private const string FROZEN_ORB = "Frozen Orb";
        private const string SPELLSTEAL = "Spellsteal";
        private const string DEEP_FREEZE = "Deep Freeze";
        private const string CONJURE_REFRESHMENT_TABLE = "Conjure Refreshment Table";
        private const string BRAIN_FREEZE = "Brain Freeze";
        private const string TIME_WARP = "Time Warp";
        private const string ALTER_TIME = "Alter Time";
        private const string ICE_NOVA = "Ice Nova";
        private const string FREEZE = "Freeze";
        private const string WATER_JET = "Water Jet";
        private const string COMET_STORM = "Comet Storm";
        //END OF SPELLS AND AURAS ==============================

        //TALENTS
        private const string ICE_FLOES = "Ice Floes";
        private const int ICE_FLOES_BUFF = 108839;
        private const string BLAZING_SPEED = "Blazing Speed";
        private const string ICE_BARRIER = "Ice Barrier";
        private const string RING_OF_FROST = "Ring of Frost";
        private const string ICE_WARD = "Ice Ward";
        private const string FROSTJAW = "Frostjaw";
        private const string GREATER_INVISIBILITY = "Greater Invisibility";

        private const string COLD_SNAP = "Cold Snap";
        private const string FROST_BOMB = "Frost Bomb";
        private const string RUNE_OF_POWER = "Rune of Power";
        private const string EVANESCE = "Evanesce";
        private const string PRISMATIC_CRYSTAL = "Prismatic Crystal";
        //END TALENTS
        //END OF CONSTANTS ==============================

        #endregion

        #region Hotkeys
        private static void InitializeHotkey()
        {
            HotkeysManager.Initialize(StyxWoW.Memory.Process.MainWindowHandle);
        }

        private static DateTime nextTime_Pause_Resume_Allowed = DateTime.Now;

        public static void SetnextTime_Pause_Resume_Allowed()
        {
            //1 seconds avoid duuble cast
            nextTime_Pause_Resume_Allowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 1000);
        }

        private static Hotkey RegisterHotkeyAssignment(string name, Keys key, Action<Hotkey> callback)
        {
            Keys keyCode = key & Keys.KeyCode;
            ModifierKeys mods = ModifierKeys.NoRepeat;

            if ((key & Keys.Shift) != 0)
                mods |= ModifierKeys.Shift;
            if ((key & Keys.Alt) != 0)
                mods |= ModifierKeys.Alt;
            if ((key & Keys.Control) != 0)
                mods |= ModifierKeys.Control;

            return HotkeysManager.Register(name, keyCode, mods, callback);
        }

        private static void RegisterHotkeys()
        {
            RegisterHotkeyAssignment("Routine Pause", (Keys)FrostMageSettings.Instance.PauseKey, hk =>
            {
                if (nextTime_Pause_Resume_Allowed < DateTime.Now)
                {
                    if (!IsCRPaused)
                    {
                        IsCRPaused = true;
                        if (ExtraUtilsSettings.Instance.ViewChatMessages) 
                            Lua.DoString(@"print('\124cFFE61515 Paused!')");
                        Logging.Write("KingWoW Routine Paused!");
                    }
                    else
                    {
                        IsCRPaused = false;
                        if (ExtraUtilsSettings.Instance.ViewChatMessages) 
                            Lua.DoString(@"print('\124cFF15E61C Resumed!')");
                        Logging.Write("KingWoW Routine Resumed!");
                    }
                    SetnextTime_Pause_Resume_Allowed();
                }
            });
            RegisterHotkeyAssignment("AvoidAOE", (Keys)FrostMageSettings.Instance.AvoidAOEKey, hk =>
            {
                FrostMageSettings.Instance.AvoidAOE = !FrostMageSettings.Instance.AvoidAOE;
                if (FrostMageSettings.Instance.AvoidAOE)
                {
                    if (ExtraUtilsSettings.Instance.ViewChatMessages) 
                        Lua.DoString(@"print('AvoidAOE \124cFF15E61C Enabled!')");
                    Logging.Write("AvoidAOE Enabled!");
                }

                else
                {
                    if (ExtraUtilsSettings.Instance.ViewChatMessages) 
                        Lua.DoString(@"print('AvoidAOE \124cFFE61515 Disabled!')");
                    Logging.Write("AvoidAOE Disabled!");
                }

            });

            RegisterHotkeyAssignment("BurstKey", (Keys)FrostMageSettings.Instance.BurstKey, hk =>
            {
                if (ExtraUtilsSettings.Instance.ViewChatMessages)
                    Lua.DoString(@"print('BURST!!!')");
                Logging.Write("BurstKeyPressed!");

                BurstModeActivated = true;
                BurstTimer.AutoReset = false;
                BurstTimer.Interval = 10000;
                BurstTimer.Start();
            });
        }

        private static bool BurstModeActivated = false;
        private static System.Timers.Timer BurstTimer = new System.Timers.Timer();

        private bool BurstHotkeyHandle()
        {
            if (BurstModeActivated)
            {
                if (utils.CanCast(ICY_VEINS) && FrostMageSettings.Instance.CDUseIcyVeins == FrostMageSettings.CDUseType.OnBURSTHOTKEY)
                {
                    utils.LogActivity("BURST HOTKEY TRY CAST:" + ICY_VEINS);
                    utils.Cast(ICY_VEINS);
                }
                if (utils.CanCast(MIRROR_IMAGE) && FrostMageSettings.Instance.CDUseMirrorImage == FrostMageSettings.CDUseType.OnBURSTHOTKEY)
                {
                    utils.LogActivity("BURST HOTKEY TRY CAST:" + MIRROR_IMAGE);
                    utils.Cast(MIRROR_IMAGE);
                }
                if (utils.CanCast(PRISMATIC_CRYSTAL) && FrostMageSettings.Instance.PrismaticCrystalOnlyOnBurst)
                {
                    if (Me.CurrentTarget != null && Me.CurrentTarget.Attackable && Me.CurrentTarget.IsValid)
                    {
                        utils.LogActivity("BURST HOTKEY TRY CAST:" + PRISMATIC_CRYSTAL, Me.CurrentTarget.SafeName);
                        utils.Cast(PRISMATIC_CRYSTAL, Me.CurrentTarget);
                        SpellManager.ClickRemoteLocation(Me.CurrentTarget.Location);
                    }
                }
            }
            return false;
        }
        private static void RemoveHotkeys()
        {
            HotkeysManager.Unregister("Routine Pause");
            HotkeysManager.Unregister("AvoidAOE");
            HotkeysManager.Unregister("BurstKey");
        }

        private static void ReRegisterHotkeys()
        {
            RemoveHotkeys();
            RegisterHotkeys();
        }
        #endregion

        public FrostMageCombatClass()
        {
            utils = new KingWoWUtility();
            movement = new Movement();
            extra = new ExtraUtils();
            tank = null;
            lastTank = null;;
            SoloBotType = false;
            BaseBot = "unknown";
            nextTimeRuneOfPowerAllowed = DateTime.Now;
            nextTimeFrostBombAllowed = DateTime.Now;
            nextTimeTryReviveAllowed = DateTime.Now;
            talents = new TalentManager();
            BurstTimer.Elapsed += BurstTimer_Elapsed;
        }

        void BurstTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (ExtraUtilsSettings.Instance.ViewChatMessages)
                Lua.DoString(@"print('BURST ENDS!!!')");
            Logging.Write("BurstModeEnd!");
            BurstModeActivated = false;
        }

        private DateTime nextTimeNormalRotationallowed = DateTime.Now;

        public void SetNextTimeNormalRotation(int time)
        {
            nextTimeNormalRotationallowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, time);
        }

        public override bool Combat
        {
            get 
            {
                if ((Me.Mounted && !FrostMageSettings.Instance.AutoDismountOnCombat)
                    || !StyxWoW.IsInGame || !StyxWoW.IsInWorld || Me.Silenced
                    || (!ExtraUtilsSettings.Instance.FastRotation && (utils.IsGlobalCooldown() || Me.IsCasting))
                    || utils.isAuraActive(DRINK) || utils.isAuraActive(FOOD) || IsCRPaused)
                    return false;

                if (ExtraUtilsSettings.Instance.UseBossLogic) 
                {
                    int time = 0;
                    time = utils.SpecificEncounterNeedStopCast();
                    if (time == 0)
                        time = utils.SpecificEncounterDontCast();
                    if (time > 0)
                    {
                        SpellManager.StopCasting();
                        utils.LogActivity("STOP CASTING/CHANNELING");
                        SetNextTimeNormalRotation(time);
                    }
                    if (nextTimeNormalRotationallowed > DateTime.Now)
                        return OnlyInstantSpellRotation();
                }

                tank = utils.SimpleGetTank(40f);
                if (tank == null || !tank.IsValid || !tank.IsAlive) tank = Me;

                if (tank != null && (lastTank == null || lastTank.Guid != tank.Guid))
                {
                    lastTank = tank;
                    utils.LogActivity(TANK_CHANGE, tank.Class.ToString());
                } off_tank = utils.SimpleGetOffTank(40f, tank);
                if (off_tank != null && (lastOffTank == null || lastOffTank.Guid != off_tank.Guid))
                {
                    lastOffTank = off_tank;
                    utils.LogActivity(OFF_TANK_CHANGE, off_tank.Class.ToString());
                }
                return CombatRotation();
            }
        }

        public override bool Pulse
        {
            get 
            {
                if (Me.IsDead) return MyDeath();
                if (Me.Combat || (Me.Mounted && !FrostMageSettings.Instance.AutoDismountOnCombat) 
                    || !StyxWoW.IsInGame || !StyxWoW.IsInWorld || Me.Silenced || utils.IsGlobalCooldown() 
                    || utils.MeIsChanneling || Me.IsCasting
                    || utils.isAuraActive(DRINK) || utils.isAuraActive(FOOD) || IsCRPaused)
                    return false;
                tank = utils.SimpleGetTank(40f);
                if (tank == null || !tank.IsValid || !tank.IsAlive) tank = Me;

                if (tank != null && (lastTank == null || lastTank.Guid != tank.Guid))
                {
                    lastTank = tank;
                    utils.LogActivity(TANK_CHANGE, tank.SafeName);
                }
                off_tank = utils.SimpleGetOffTank(40f, tank);
                if (off_tank != null && (lastOffTank == null || lastOffTank.Guid != off_tank.Guid))
                {
                    lastOffTank = off_tank;
                    utils.LogActivity(OFF_TANK_CHANGE, off_tank.SafeName);
                }
                if (!Me.Combat && ((tank != null && tank.Combat) || (off_tank != null && off_tank.Combat)))
                    return CombatRotation();
                return false; 
            }
        }

        private DateTime nextTimeTryReviveAllowed;

        public void SetNextTimeTryRevive()
        {
            //2 seconds avoid duuble cast
            nextTimeTryReviveAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 3000);
        }

        private bool MyDeath()
        {
            if (SoloBotType && Me.IsDead && !Me.IsGhost && nextTimeTryReviveAllowed < DateTime.Now)
            {
                Lua.DoString(string.Format("RunMacroText(\"{0}\")", "/script RepopMe()"));
                SetNextTimeTryRevive();
            }
            return false;
        }

        public override bool Pull
        {
            get
            {
                target = Me.CurrentTarget;
                if (target != null && target.IsDead)
                {
                    Me.ClearTarget();
                    target = utils.getTargetToAttack(40, tank, false, ExtraUtilsSettings.Instance.UseBossLogic);
                    target.Target();
                }
                if ((SoloBotType || FrostMageSettings.Instance.movementEnabled) && Me.CurrentTarget != null && Me.IsMoving && Me.CurrentTarget.InLineOfSpellSight && Me.CurrentTarget.Distance - Me.CurrentTarget.CombatReach - 1 <= FrostMageSettings.Instance.PullDistance)
                {
                    Navigator.PlayerMover.MoveStop();
                }
                if (target != null && !target.IsFriendly && target.Attackable && !target.IsDead && !IsCRPaused)
                {
                    if (FrostMageSettings.Instance.UsePet && !Me.GotAlivePet && utils.CanCast(SUMMON_WATER_ELEMENTAL) && !Me.IsMoving)
                    {
                        utils.LogActivity(SUMMON_WATER_ELEMENTAL);
                        return utils.Cast(SUMMON_WATER_ELEMENTAL);
                    }
                    if (!target.InLineOfSpellSight || target.Distance - target.CombatReach -1 > FrostMageSettings.Instance.PullDistance)
                    {
                        movement.KingHealMove(target, FrostMageSettings.Instance.PullDistance);
                    }
                    if (!Me.IsMoving && !Me.IsFacing(target))
                    {
                        utils.LogActivity(FACING, target.SafeName);
                        Me.SetFacing(target);
                    }

                    if (utils.isAuraActive(BRAIN_FREEZE) && utils.CanCast(FROSTFIRE_BOLT, target))
                    {
                        utils.LogActivity(FROSTFIRE_BOLT, target.SafeName);
                        return utils.Cast(FROSTFIRE_BOLT, target);
                    }

                    utils.LogActivity(ICE_LANCE, target.SafeName);
                    return utils.Cast(ICE_LANCE, target);
                }
                return false;
            }
        }

        public override bool Initialize
        {
            get
            {
                Logging.Write("Ciao " + Me.Class.ToString());
                Logging.Write("Welcome to " + Name + " custom class");
                Logging.Write("Tanks All HonorBuddy Forum developers for code inspiration!");
                Logging.Write("Powered by Attilio76");
                BotEvents.OnBotStartRequested += new BotEvents.OnBotStartStopRequestedDelegate(BotEvents_OnBotStart);
               
                Logging.Write("Initializing Hotkey");
                InitializeHotkey();
                RegisterHotkeys();
                Logging.Write("************ XML CONFIGURATION ************");
                Logging.Write(FrostMageSettings.Instance.GetXML().ToString());
                Logging.Write("*******************************************");
                Logging.Write("*******************************************");
                Logging.Write("*******************************************");
                Logging.Write("************ EXTRA CONFIGURATION ************");
                Logging.Write(ExtraUtilsSettings.Instance.GetXML().ToString());
                Logging.Write("*******************************************");
                return true;
            }
        }

        void BotEvents_OnBotStart(EventArgs args)
        {
            ReRegisterHotkeys();
            talents.Update();
            BotUpdate();
        }

        public override bool UpdateTalentAndGlyph
        {
            get
            {
                ReRegisterHotkeys();
                talents.Update();
                BotUpdate();
                return true;

            }
        }

        public override bool NeedCombatBuffs { get { return Buff(); } }

        public override bool NeedPreCombatBuffs { get { return Buff(); } }

        public override bool NeedPullBuffs { get { return Buff(); } }

        public override bool NeedRest
        {
            get
            {
                if (Me.IsDead || Me.Mounted || Me.InVehicle || (Me.HealthPercent >= 100 && Me.ManaPercent >= 100) ) return false;
                if (utils.IsEatingOrDrinking())
                    return true;
                if (!Me.IsCasting && !utils.IsGlobalCooldown() && !utils.GotMagefood && utils.CanCast(CONJURE_REFRESHMENT))
                {
                    utils.LogActivity(CONJURE_REFRESHMENT);
                    return utils.Cast(CONJURE_REFRESHMENT);
                }
                if (Me.ManaPercent <= FrostMageSettings.Instance.ManaPercent
                    && !Me.Combat && !Me.IsMoving && !utils.IsEatingOrDrinking())
                {
                    WoWItem mydrink = Consumable.GetBestDrink(false);
                    if (mydrink != null)
                    {
                        utils.LogActivity("Drinking");
                        Styx.CommonBot.Rest.DrinkImmediate();
                        return true;
                    }
                    return true;
                }
                if (Me.HealthPercent <= FrostMageSettings.Instance.HealthPercent
                    && !Me.Combat && !Me.IsMoving && !utils.IsEatingOrDrinking())
                {
                    WoWItem myfood = Consumable.GetBestFood(false);
                    if (myfood != null)
                    {
                        utils.LogActivity("Eating");
                        Styx.CommonBot.Rest.DrinkImmediate();
                        return true;
                    }
                    return true;
                }
                return false;
            }
        }

        public void SetNextTimeRuneOfPower()
        {
            //3 seconds wait to avoid popping 2 rune of frost cause has high priority
            nextTimeRuneOfPowerAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 3000);
        }

        public void SetNextTimeFrostBomb()
        {
            //2 seconds avoid duuble cast
            nextTimeFrostBombAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 2000);
        }

        private bool PriorityBuff()
        {
            if (FrostMageSettings.Instance.UseRuneOfPower && !Me.IsMoving && nextTimeRuneOfPowerAllowed < DateTime.Now && !utils.isAuraActive(RUNE_OF_POWER, Me) && Me.Combat && utils.CanCast(RUNE_OF_POWER))
            {
                utils.LogActivity(RUNE_OF_POWER);
                utils.Cast(RUNE_OF_POWER);
                SetNextTimeRuneOfPower();
                return SpellManager.ClickRemoteLocation(Me.Location);
            }

            if (Me.Combat && FrostMageSettings.Instance.UseIcebarrier && utils.CanCast(ICE_BARRIER) && Me.HealthPercent <= FrostMageSettings.Instance.IcebarrierHP && !utils.isAuraActive(ICE_BARRIER))
            {
                utils.LogActivity(ICE_BARRIER);
                return utils.Cast(ICE_BARRIER);
            }

            if (FrostMageSettings.Instance.IceWardOnTank && Me.Combat && (tank != null && tank.Combat) && utils.CanCast(ICE_WARD) &&
                !utils.isAuraActive(ICE_WARD, tank) && tank != null && tank.IsAlive && tank.Distance2DSqr < 40 * 40 &&
                tank.InLineOfSpellSight)
            {
                utils.LogActivity(ICE_WARD, tank.Class.ToString());
                return utils.Cast(ICE_WARD, tank);
            }
            return false;
        }

        private bool Buff()
        {
            if (Me.Mounted || IsCRPaused || Me.InVehicle
                    || !StyxWoW.IsInGame || !StyxWoW.IsInWorld || Me.Silenced
                    || utils.isAuraActive(DRINK) || utils.isAuraActive(FOOD)
                /*|| utils.MeIsCastingWithLag()*/)
                return false;

            //arcane brillance
            if (FrostMageSettings.Instance.AutoBuffBrillance && !utils.isAuraActive(ARCANE_BRILLANCE) && utils.CanCast(ARCANE_BRILLANCE))
            {
                utils.LogActivity(ARCANE_BRILLANCE);
                return utils.Cast(ARCANE_BRILLANCE);
            }
            //Water Elemental
            if (!FrostMageSettings.Instance.UsePet && Me.GotAlivePet)
            {
                utils.LogActivity("Dismissing Pet");
                Lua.DoString("PetDismiss()");
                return true;
            }
            else if (FrostMageSettings.Instance.UsePet && !Me.GotAlivePet && utils.CanCast(SUMMON_WATER_ELEMENTAL) && !Me.IsMoving)
            {
                utils.LogActivity(SUMMON_WATER_ELEMENTAL);
                return utils.Cast(SUMMON_WATER_ELEMENTAL);
            }
            return false;
        }

        private bool Interrupt()
        {
            if (FrostMageSettings.Instance.AutoInterrupt)
            {
                WoWUnit InterruptTargetCandidate = Me.FocusedUnit;
                if (InterruptTargetCandidate == null || InterruptTargetCandidate.IsFriendly || InterruptTargetCandidate.IsDead
                    || !InterruptTargetCandidate.Attackable || !InterruptTargetCandidate.InLineOfSpellSight
                    || InterruptTargetCandidate.Distance - InterruptTargetCandidate.CombatReach - 1 > 40f)
                {
                    if (Me.CurrentTarget != null && Me.CurrentTarget.Distance - Me.CurrentTarget.CombatReach - 1 <= 40f && Me.CurrentTarget.InLineOfSpellSight)
                        InterruptTargetCandidate = Me.CurrentTarget;
                    else if (target != null && target.Distance - target.CombatReach - 1 <= 40f && target.InLineOfSpellSight)
                        InterruptTargetCandidate = target;
                }
                if (InterruptTargetCandidate != null && (InterruptTargetCandidate.IsCasting || InterruptTargetCandidate.IsChanneling)
                    && InterruptTargetCandidate.CanInterruptCurrentSpellCast && utils.CanCast(COUNTERSPELL, InterruptTargetCandidate)
                    && Me.IsFacing(InterruptTargetCandidate)
                    && InterruptTargetCandidate.Distance - InterruptTargetCandidate.CombatReach - 1 <= 40f
                    && InterruptTargetCandidate.InLineOfSpellSight)
                {
                    RANDOM_TIME = rnd.Next(FrostMageSettings.Instance.Interrupt_MIN_Time, FrostMageSettings.Instance.Interrupt_MAX_Time);

                    if (InterruptTargetCandidate.CurrentCastStartTime.AddMilliseconds(RANDOM_TIME) <= DateTime.Now)
                    {
                        utils.LogActivity(COUNTERSPELL, InterruptTargetCandidate.SafeName);
                        return utils.Cast(COUNTERSPELL, InterruptTargetCandidate);
                    }
                }
            }
            return false;
        }

        private bool ProcWork()
        {
            if (Me.IsFacing(target))
            {
                if (PrismaticCrystal()) return true;
                if (Me.IsChanneling && Me.ChanneledSpell.Name.Equals(BLIZZARD))
                {
                    if (utils.GetSpellCooldown(FROZEN_ORB).Milliseconds == 0
                        && FrostMageSettings.Instance.AutoFrozerOrb && !Me.IsMoving && Me.IsSafelyFacing(target, 45)
                        && !FrostMageSettings.Instance.AvoidAOE)
                    {
                        utils.LogActivity(FROZEN_ORB, target.SafeName);
                        return utils.Cast(FROZEN_ORB, target);
                    }
                    if (utils.isAuraActive(FINGER_OF_FROST))
                    {
                        utils.LogActivity(ICE_LANCE, target.SafeName);
                        return utils.Cast(ICE_LANCE, target);
                    }
                }

                if (utils.PlayerCountBuff(FINGER_OF_FROST) >= 2)
                {
                    utils.LogActivity(ICE_LANCE, target.SafeName);
                    return utils.Cast(ICE_LANCE, target);
                }

                if (utils.isAuraActive(BRAIN_FREEZE)
                    && !(Me.Pet != null && Me.Pet.IsAlive && Me.Pet.CastingSpellId == 135029))
                {
                    utils.LogActivity(FROSTFIRE_BOLT, target.SafeName);
                    return utils.Cast(FROSTFIRE_BOLT, target);
                }

                if (Me.Pet != null && Me.Pet.IsAlive && utils.CanCastPetAction(WATER_JET) && (utils.IsBoss(target) || !FrostMageSettings.Instance.UsePetFreeze)
                    && !utils.isMyAuraActive(FROZEN_ORB, target) && !utils.CanCast(FROZEN_ORB) && !(Me.Pet.CastingSpellId == 135029) && !utils.isAuraActive(FINGER_OF_FROST)
                    && !utils.isAuraActive(BRAIN_FREEZE) && Me.IsCasting && Me.CastingSpell.Name.Equals(FROSTBOLT))
                {
                    utils.LogActivity(WATER_JET, target.SafeName);
                    utils.CastPetAction(WATER_JET);
                }
                if (utils.isAuraActive(FINGER_OF_FROST) 
                    && (!(Me.Pet != null && Me.Pet.IsAlive && Me.Pet.CastingSpellId == 135029 && utils.PlayerCountBuff(FINGER_OF_FROST) <= 1) || utils.PlayerCountBuff(FINGER_OF_FROST) >= 2) )
                {
                    if (utils.CanCast(FROST_BOMB, target) && !utils.isMyAuraActive(FROST_BOMB, target) && nextTimeFrostBombAllowed < DateTime.Now
                        && target.Entry != 76933)
                    {
                        utils.LogActivity(FROST_BOMB, target.SafeName);
                        SetNextTimeFrostBomb();
                        return utils.Cast(FROST_BOMB, target);
                    }
                    if ((talents.IsSelected(13) && utils.isMyAuraActive(FROST_BOMB, target)) || !talents.IsSelected(13) || target.Entry == 76933)
                    {
                        utils.LogActivity(ICE_LANCE, target.SafeName);
                        return utils.Cast(ICE_LANCE, target);
                    }
                }

                
                if (talents.IsSelected(19) && Me.HasAura(ICY_VEINS) && Me.GetAuraByName(ICY_VEINS).TimeLeft.TotalMilliseconds <= FrostMageSettings.Instance.spamIceLanceForIcyVeinsTimer)
                {
                    utils.LogActivity("Spam IceLance to prolungate IcyVeins: " + ICE_LANCE, target.SafeName);
                    return utils.Cast(ICE_LANCE, target);
                }


            }
            return false;
        }

        private bool BotUpdate()
        {
            if (BaseBot.Equals(BotManager.Current.Name))
                return false;
            if (utils.IsBotBaseInUse("LazyRaider") || utils.IsBotBaseInUse("Tyrael")
                || utils.IsBotBaseInUse("Raid Bot") || utils.IsBotBaseInUse("Enyo"))
            {
                SoloBotType = false;
                BaseBot = BotManager.Current.Name;
                Logging.Write("Base bot detected: " + BotManager.Current.Name);
                return true;
            }

            Logging.Write("Base bot detected: " + BotManager.Current.Name);
            SoloBotType = true;
            BaseBot = BotManager.Current.Name;
            return true;


        }

        private bool Defensivececk()
        {
            if (Me.Combat && FrostMageSettings.Instance.EvanesceUse && utils.CanCast(EVANESCE) && Me.HealthPercent < FrostMageSettings.Instance.EvanesceHP && !StyxWoW.Me.ActiveAuras.ContainsKey("Hypothermia"))
            {
                utils.LogActivity(EVANESCE, Me.Class.ToString());
                return utils.Cast(EVANESCE);
            }

            if (Me.Combat && FrostMageSettings.Instance.IceBlockUse && utils.CanCast(ICE_BLOCK) && Me.HealthPercent < FrostMageSettings.Instance.IceBlockHP && !StyxWoW.Me.ActiveAuras.ContainsKey("Hypothermia"))
            {
                utils.LogActivity(ICE_BLOCK, Me.Class.ToString());
                return utils.Cast(ICE_BLOCK);
            }

            if (Me.Combat && FrostMageSettings.Instance.ColdSnapUse && utils.CanCast(COLD_SNAP) && Me.HealthPercent < FrostMageSettings.Instance.ColdSnapHP)
            {
                utils.LogActivity(COLD_SNAP, Me.Class.ToString());
                return utils.Cast(COLD_SNAP);
            }

            if (Me.Combat && !talents.IsSelected(15) && FrostMageSettings.Instance.UseFrostNova && utils.CanCast(FROST_NOVA) && (utils.AllAttaccableEnemyMobsInRange(12).Count() >= 1))
            {
                utils.LogActivity(FROST_NOVA);
                utils.Cast(FROST_NOVA);
            }

            if (Me.Combat && FrostMageSettings.Instance.UseBlink && utils.CanCast(BLINK) && Me.IsMoving && (utils.AllAttaccableEnemyMobsInRange(12).Count() >= 1))
            {
                utils.LogActivity(BLINK);
                return utils.Cast(BLINK);
            }
            return false;
        }

        private bool Decursing()
        {
            if (FrostMageSettings.Instance.UseDecurse && utils.CanCast(REMOVE_CURSE))
            {
                WoWUnit player = null;
                if (utils.NeedsDeCurse(Me))
                    player = Me;
                else player = utils.GetDecurseTarget(40f);

                if (player != null && player.Distance - player.CombatReach -1  <= 40f && player.InLineOfSpellSight)
                {
                    utils.LogActivity(REMOVE_CURSE, player.Class.ToString());
                    return utils.Cast(REMOVE_CURSE, player);
                }
            }
            return false;
        }

        private bool SpellSteal()
        {
            if (FrostMageSettings.Instance.UseSpellSteal)
            {
                WoWUnit CandidateUnit = null;
                if (Me.FocusedUnit != null && Me.FocusedUnit.Attackable && Me.FocusedUnit.Distance - Me.FocusedUnit.CombatReach -1  <= 30 && Me.FocusedUnit.InLineOfSpellSight)
                    CandidateUnit = Me.FocusedUnit;
                else if (Me.CurrentTarget != null && Me.CurrentTarget.Attackable && Me.CurrentTarget.Distance - Me.CurrentTarget.CombatReach -1  <= 30 && Me.CurrentTarget.InLineOfSpellSight)
                    CandidateUnit = Me.CurrentTarget;
                if (CandidateUnit != null && utils.CanCast(SPELLSTEAL, CandidateUnit, true))
                    return SpellStealOnUnit(CandidateUnit);
            }

            return false;
        }

        private bool SpellStealOnUnit(WoWUnit u)
        {
            foreach (string spell in StealBuffs)
            {
                if (u.HasAura(spell) && !StyxWoW.Me.HasAura(spell) && StyxWoW.Me.ManaPercent > 40)
                {
                    utils.LogActivity(SPELLSTEAL + spell, u.SafeName);
                    return utils.Cast(SPELLSTEAL, u);
                }
            }
            return false;
        }

        private bool IsViableForPolymorph(WoWUnit unit)
        {
            if (utils.IsCrowdControlledPlayer(unit))
                return false;

            if (unit.CreatureType != WoWCreatureType.Beast && unit.CreatureType != WoWCreatureType.Humanoid)
                return false;

            if (StyxWoW.Me.CurrentTarget != null && StyxWoW.Me.CurrentTarget == unit)
                return false;

           /*if (StyxWoW.Me.GroupInfo.IsInParty && StyxWoW.Me.PartyMembers.Any(p => p.CurrentTarget != null && p.CurrentTarget == unit))
                return false;*/

            return true;
        }

        private bool Polymorf()
        {
            if (FrostMageSettings.Instance.UsePolymorf)
            {
                if (Me.FocusedUnit != null && Me.FocusedUnit.Attackable && Me.FocusedUnit.Distance - Me.FocusedUnit.CombatReach -1  <= 30
                    && Me.FocusedUnit.InLineOfSpellSight && IsViableForPolymorph(Me.FocusedUnit) && utils.CanCast(POLYMORPH,Me.FocusedUnit,true))
                {
                    utils.LogActivity(POLYMORPH, Me.FocusedUnit.SafeName);
                    return utils.Cast(POLYMORPH, Me.FocusedUnit);
                }
                    
            }
            return false;

        }

        private DateTime nextTimeIceFloesAllowed = DateTime.Now;

        public void SetNextTimeIceFloesAllowed()
        {
            //1 seconds wait to avoid popping 2 rune of frost cause has high priority
            nextTimeIceFloesAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 1000);
        }

        private void SetTargetToAttack()
        {
            if (FrostMageSettings.Instance.TargetTypeSelected == FrostMageSettings.TargetType.AUTO)
            {
                if (ExtraUtilsSettings.Instance.provinGround_Targeting)
                    target = utils.getAnyTargetToAttack(40f);
                else
                    target = utils.getTargetToAttack(40, tank, false, ExtraUtilsSettings.Instance.UseBossLogic);
                if (target != null)
                    target.Target();
            }
            else
                target = Me.CurrentTarget;
        }

        private bool OnlyInstantSpellRotation()
        {
            SetTargetToAttack();
            extra.UseHealPotion_Healthstone();
            while (extra.UseRacials()) return true;
            while (extra.UseTrinket1()) return true;
            while (extra.UseTrinket2()) return true;
            extra.UseManaItem();
            while (Defensivececk()) return true;
            while (Interrupt()) return true;
            while (PriorityBuff()) return true;
            while (SpellSteal()) return true;
            while (Polymorf()) return true;
            while (Decursing()) return true;

            if ((SoloBotType || FrostMageSettings.Instance.movementEnabled) && Me.CurrentTarget != null && Me.IsMoving && Me.CurrentTarget.InLineOfSpellSight && Me.CurrentTarget.Distance - Me.CurrentTarget.CombatReach - 1 <= FrostMageSettings.Instance.PullDistance)
            {
                Navigator.PlayerMover.MoveStop();
            }

            if (target != null)
            {
                if ((FrostMageSettings.Instance.AutofaceTarget || SoloBotType) && !Me.IsMoving)
                {
                    Me.SetFacing(target);
                }
                while (BurstHotkeyHandle()) return true;
                while (ProcWork()) return true;
                while (UseCD()) return true;


                if (utils.CanCast(ICE_NOVA) && (!talents.IsSelected(18) || (talents.IsSelected(18) && utils.PlayerCountBuff("Incanter's Flow") == 5) || FrostMageSettings.Instance.iceNovaOnCooldown) && !FrostMageSettings.Instance.AvoidAOE)
                {
                    IceNovaCandidateTarget = utils.EnemyInRangeWithMobsAround(40, 10, FrostMageSettings.Instance.IceNovaCount,false, ExtraUtilsSettings.Instance.provinGround_Targeting);
                    if (IceNovaCandidateTarget == null && FrostMageSettings.Instance.IceNovaOnSingle)
                        IceNovaCandidateTarget = target;
                    if (IceNovaCandidateTarget != null)
                    {
                        if (!Me.IsFacing(IceNovaCandidateTarget) && !Me.IsMoving)
                            Me.SetFacing(IceNovaCandidateTarget);
                        utils.LogActivity(ICE_NOVA, IceNovaCandidateTarget.SafeName);
                        return utils.Cast(ICE_NOVA, IceNovaCandidateTarget);
                    }
                }
                if (utils.CanCast(COMET_STORM) && (!talents.IsSelected(18) || (talents.IsSelected(18) && utils.PlayerCountBuff("Incanter's Flow") == 5) || FrostMageSettings.Instance.cometStormOnCooldown) && !FrostMageSettings.Instance.AvoidAOE)
                {
                    CometStormCandidateTarget = utils.EnemyInRangeWithMobsAround(40, 4, FrostMageSettings.Instance.CometStormCount, true, ExtraUtilsSettings.Instance.provinGround_Targeting);
                    if (CometStormCandidateTarget == null && FrostMageSettings.Instance.CometStormOnSingle)
                        CometStormCandidateTarget = target;
                    if (CometStormCandidateTarget != null)
                    {
                        if (!Me.IsFacing(CometStormCandidateTarget) && !Me.IsMoving)
                            Me.SetFacing(CometStormCandidateTarget);
                        if (Me.IsFacing(CometStormCandidateTarget))
                        {
                            utils.LogActivity(COMET_STORM, CometStormCandidateTarget.SafeName);
                            return utils.Cast(COMET_STORM, CometStormCandidateTarget);
                        }
                    }

                }

                //Cast  Freeze from your Water Elemental every time it is available.
                //This will give you 1 charge of  Fingers of Frost (2 if it hits more than 1 enemy).
                if (FrostMageSettings.Instance.UsePetFreeze && Me.Pet != null && Me.Pet.IsAlive && utils.CanCastPetAction(FREEZE) && target.Distance <= 45
                    && !utils.IsBoss(target) && !FrostMageSettings.Instance.AvoidAOE)
                {
                    if (Me.Pet.Distance <= 10 && Me.Pet.InLineOfSight)
                    {
                        utils.LogActivity(FREEZE, target.SafeName);
                        utils.CastPetAction(FREEZE);
                        SpellManager.ClickRemoteLocation(target.Location);
                    }
                    else if (Me.Pet.IsAlive)
                    {
                        utils.LogActivity("Command Pet Follow Me");
                        utils.CastPetAction("Follow");
                    }
                }

                if (Me.IsFacing(target))
                {
                    //Cast  Frozen Orb on cooldown.
                    if (FrostMageSettings.Instance.AutoFrozerOrb && !Me.IsMoving && Me.IsSafelyFacing(target,45)
                        && utils.CanCast(FROZEN_ORB) && !FrostMageSettings.Instance.AvoidAOE)
                    {
                        if (utils.CanCast(FROST_BOMB) && !utils.isMyAuraActive(FROST_BOMB, target) && nextTimeFrostBombAllowed < DateTime.Now
                            && target.Entry != 76933)
                        {
                            utils.LogActivity(FROST_BOMB, target.SafeName);
                            SetNextTimeFrostBomb();
                            utils.Cast(FROST_BOMB, target);
                        }
                        if ((talents.IsSelected(13) && utils.isMyAuraActive(FROST_BOMB, target)) || !talents.IsSelected(13))
                        {
                            utils.LogActivity(FROZEN_ORB, target.SafeName);
                            return utils.Cast(FROZEN_ORB, target);
                        }
                    }

                    if (talents.IsSelected(19) && Me.HasAura(ICY_VEINS) && Me.GetAuraByName(ICY_VEINS).TimeLeft.TotalMilliseconds <= FrostMageSettings.Instance.spamIceLanceForIcyVeinsTimer)
                    {
                        utils.LogActivity("Spam IceLance to prolungate IcyVeins: " + ICE_LANCE, target.SafeName);
                        return utils.Cast(ICE_LANCE, target);
                    }

                    //Cone Of Cold
                    if (FrostMageSettings.Instance.UseConeOfCold && utils.CanCast(CONE_OF_COLD) && !FrostMageSettings.Instance.AvoidAOE && utils.FacingEnemy(12, ExtraUtilsSettings.Instance.provinGround_Targeting).Count() >= FrostMageSettings.Instance.ConeOfColdCount)
                    {
                        utils.LogActivity(CONE_OF_COLD);
                        utils.Cast(CONE_OF_COLD);
                    }

                    //Frozen Target!
                    /*if (Me.CurrentTarget != null && utils.HasAnyAura(Me.CurrentTarget,  44572, 122, 33395))
                    {
                        utils.LogActivity("FROZEN TARGET!!" + ICE_LANCE, Me.CurrentTarget.SafeName);
                        return utils.Cast(ICE_LANCE, Me.CurrentTarget);
                    }*/

                    

                    if (Me.IsMoving && utils.CanCast(ICE_LANCE, target) && Me.IsSafelyFacing(target))
                    {
                        utils.LogActivity(ICE_LANCE, target.SafeName);
                        return utils.Cast(ICE_LANCE, target);
                    }
                }
            }
            return false;
        }

        private bool CombatRotation()
        {
            SetTargetToAttack();
            extra.UseHealPotion_Healthstone();
            while (extra.UseRacials()) return true;
            while (extra.UseTrinket1()) return true;
            while (extra.UseTrinket2()) return true;
            extra.UseManaItem();
            while (Defensivececk()) return true;
            while (Interrupt()) return true;
            while (PriorityBuff()) return true;
            while (SpellSteal()) return true;
            while (Polymorf()) return true;
            while (Decursing()) return true;

            if ((SoloBotType || FrostMageSettings.Instance.movementEnabled) && Me.CurrentTarget != null && Me.IsMoving && Me.CurrentTarget.InLineOfSpellSight && Me.CurrentTarget.Distance - Me.CurrentTarget.CombatReach - 1 <= FrostMageSettings.Instance.PullDistance)
            {
                Navigator.PlayerMover.MoveStop();
            }

            if (target != null)
            {
                if ((FrostMageSettings.Instance.AutofaceTarget || SoloBotType) && !Me.IsMoving)
                {
                    Me.SetFacing(target);
                }
                while (BurstHotkeyHandle()) return true;
                while (ProcWork()) return true;
                while (UseCD()) return true;

                if (utils.CanCast(ICE_NOVA) && (!talents.IsSelected(18) || (talents.IsSelected(18) && utils.PlayerCountBuff("Incanter's Flow") == 5)) && !FrostMageSettings.Instance.AvoidAOE)
                {
                    IceNovaCandidateTarget = utils.EnemyInRangeWithMobsAround(40, 10, FrostMageSettings.Instance.IceNovaCount, false, ExtraUtilsSettings.Instance.provinGround_Targeting);
                    if (IceNovaCandidateTarget == null && FrostMageSettings.Instance.IceNovaOnSingle)
                        IceNovaCandidateTarget = target;
                    if (IceNovaCandidateTarget != null)
                    {
                        if (!Me.IsFacing(IceNovaCandidateTarget) && !Me.IsMoving)
                            Me.SetFacing(IceNovaCandidateTarget);
                        utils.LogActivity(ICE_NOVA, IceNovaCandidateTarget.SafeName);
                        return utils.Cast(ICE_NOVA, IceNovaCandidateTarget);
                    }
                }
                if (utils.CanCast(COMET_STORM) && (!talents.IsSelected(18) || (talents.IsSelected(18) && utils.PlayerCountBuff("Incanter's Flow") == 5)) && !FrostMageSettings.Instance.AvoidAOE)
                {
                    CometStormCandidateTarget = utils.EnemyInRangeWithMobsAround(40, 4, FrostMageSettings.Instance.CometStormCount, true, ExtraUtilsSettings.Instance.provinGround_Targeting);
                    if (CometStormCandidateTarget == null && FrostMageSettings.Instance.CometStormOnSingle)
                        CometStormCandidateTarget = target;
                    if (CometStormCandidateTarget != null)
                    {
                        if (!Me.IsFacing(CometStormCandidateTarget) && !Me.IsMoving)
                            Me.SetFacing(CometStormCandidateTarget);
                        if (Me.IsFacing(CometStormCandidateTarget))
                        {
                            utils.LogActivity(COMET_STORM, CometStormCandidateTarget.SafeName);
                            return utils.Cast(COMET_STORM, CometStormCandidateTarget);
                        }
                    }

                }
                //Cast  Freeze from your Water Elemental every time it is available.
                //This will give you 1 charge of  Fingers of Frost (2 if it hits more than 1 enemy).
                if (FrostMageSettings.Instance.UsePetFreeze && Me.Pet != null && Me.Pet.IsAlive && utils.CanCastPetAction(FREEZE) && target.Distance <= 45
                    && !utils.IsBoss(target) && !FrostMageSettings.Instance.AvoidAOE)
                {
                    if (Me.Pet.Distance <= 8)
                    {
                        utils.LogActivity(FREEZE, target.SafeName);
                        utils.CastPetAction(FREEZE);
                        SpellManager.ClickRemoteLocation(target.Location);
                    }
                    else if (Me.Pet.IsAlive)
                    {
                        utils.LogActivity("Command Pet Follow Me");
                        utils.CastPetAction("Follow");
                    }
                }

                if (Me.IsFacing(target))
                {

                    //Cast  Frozen Orb on cooldown.
                    if (FrostMageSettings.Instance.AutoFrozerOrb && !Me.IsMoving && Me.IsSafelyFacing(target, 45)
                        && utils.CanCast(FROZEN_ORB) && !FrostMageSettings.Instance.AvoidAOE)
                    {
                        utils.LogActivity(FROZEN_ORB, target.SafeName);
                        return utils.Cast(FROZEN_ORB, target);
                    }

                    if (FrostMageSettings.Instance.UseConeOfCold && utils.CanCast(CONE_OF_COLD) && !FrostMageSettings.Instance.AvoidAOE && utils.FacingEnemy(12, ExtraUtilsSettings.Instance.provinGround_Targeting).Count() >= FrostMageSettings.Instance.ConeOfColdCount)
                    {
                        utils.LogActivity(CONE_OF_COLD);
                        return utils.Cast(CONE_OF_COLD);
                    }

                    if (FrostMageSettings.Instance.UseBlizzard && utils.CanCast(BLIZZARD) && !FrostMageSettings.Instance.AvoidAOE)// && target.Distance - target.CombatReach - 1 <= 35 && utils.AllAttaccableEnemyMobsInRangeFromTarget(target, 8).Count() >= FrostMageSettings.Instance.BlizzAOECount)
                    {
                        blizzardCandidateTarget = utils.EnemyInRangeWithMobsAround(35, 10, FrostMageSettings.Instance.BlizzardAOECount, false, ExtraUtilsSettings.Instance.provinGround_Targeting);
                        if (blizzardCandidateTarget != null)
                        {
                            utils.LogActivity(BLIZZARD, blizzardCandidateTarget.SafeName);
                            utils.Cast(BLIZZARD);
                            return SpellManager.ClickRemoteLocation(blizzardCandidateTarget.Location);
                        }
                    }

                    /*if (Me.CurrentTarget != null && utils.HasAnyAura(Me.CurrentTarget,  44572,  122, 33395,  157997))
                    {
                        utils.LogActivity("FROZEN TARGET!!" + ICE_LANCE, Me.CurrentTarget.SafeName);
                        return utils.Cast(ICE_LANCE, Me.CurrentTarget);
                    }*/         
                    if (FrostMageSettings.Instance.UseRingOfFrost && utils.CanCast(RING_OF_FROST) && target.Distance - target.CombatReach - 1 <= 30)
                    {
                        utils.LogActivity(RING_OF_FROST, target.SafeName);
                        utils.Cast(RING_OF_FROST);
                        return SpellManager.ClickRemoteLocation(target.Location);
                    }
                    //Cast  Frostbolt as a filler spell.
                    if (!Me.IsCasting && !Me.IsChanneling && (!Me.IsMoving || utils.isAuraActive(ICE_FLOES_BUFF)) && !utils.IsGlobalCooldown() 
                        /*&& utils.CanCast(FROSTBOLT) */
                        && !(utils.PlayerCountBuff(FINGER_OF_FROST) == 2) 
                        && (!utils.isAuraActive(BRAIN_FREEZE) 
                            || !(Me.Pet != null && Me.Pet.IsAlive && Me.Pet.CastingSpellId == 135029 && utils.PlayerCountBuff(FINGER_OF_FROST) == 2) )
                        && (!utils.isAuraActive(FINGER_OF_FROST) 
                             || !(Me.Pet != null && Me.Pet.IsAlive && Me.Pet.CastingSpellId == 135029 && utils.PlayerCountBuff(FINGER_OF_FROST) == 2) )
                        )
                    {
                        utils.LogActivity(FROSTBOLT, target.SafeName);
                        return utils.Cast(FROSTBOLT, target);
                    }

                    if ((Me.IsMoving && !utils.isAuraActive(ICE_FLOES_BUFF)) && utils.CanCast(ICE_LANCE, target) && Me.IsSafelyFacing(target))
                    {
                        utils.LogActivity(ICE_LANCE, target.SafeName);
                        return utils.Cast(ICE_LANCE, target);
                    }

                    //ICE_FLOE
                    if (FrostMageSettings.Instance.autoIceFloes && nextTimeIceFloesAllowed < DateTime.Now && Me.IsMoving && utils.CanCast(ICE_FLOES) && !utils.isAuraActive(ICE_FLOES_BUFF))
                    {
                        utils.LogActivity(ICE_FLOES);
                        utils.Cast(ICE_FLOES);
                        SetNextTimeIceFloesAllowed();
                    }
                    if (utils.isAuraActive(ICE_FLOES_BUFF) && utils.CanCast(FROSTBOLT, target))
                    {
                        utils.LogActivity(FROSTBOLT, target.SafeName);
                        return utils.Cast(FROSTBOLT, target);
                    }
                    if ((SoloBotType || FrostMageSettings.Instance.movementEnabled) && Me.IsMoving && target.InLineOfSpellSight && target.Distance - target.CombatReach - 1 <= FrostMageSettings.Instance.PullDistance)
                    {
                        Navigator.PlayerMover.MoveStop();
                    }
            
                }
            }

            else if (FrostMageSettings.Instance.movementEnabled && Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && (!Me.CurrentTarget.InLineOfSpellSight || Me.CurrentTarget.Distance - Me.CurrentTarget.CombatReach - 1 > FrostMageSettings.Instance.PullDistance))
            {
                movement.KingHealMove(Me.CurrentTarget, FrostMageSettings.Instance.PullDistance);
            }
            
            return false;
        }

        private bool UseCD()
        {
            if (Me.Combat && Me.GotTarget)
            {
                if (utils.CanCast(ICY_VEINS) && !Me.HasAura(ICY_VEINS) && FrostMageSettings.Instance.CDUseIcyVeins == FrostMageSettings.CDUseType.COOLDOWN)
                {
                    utils.LogActivity(ICY_VEINS);
                    return utils.Cast(ICY_VEINS);
                }
                if (utils.CanCast(MIRROR_IMAGE) && FrostMageSettings.Instance.CDUseMirrorImage == FrostMageSettings.CDUseType.COOLDOWN)
                {
                    utils.LogActivity(MIRROR_IMAGE);
                    return utils.Cast(MIRROR_IMAGE);
                }
                

                if (extra.IsTargetBoss())
                {
                    if (utils.CanCast(ICY_VEINS) && FrostMageSettings.Instance.CDUseIcyVeins == FrostMageSettings.CDUseType.BOSS)
                    {
                        utils.LogActivity(ICY_VEINS);
                        return utils.Cast(ICY_VEINS);
                    }
                    if (utils.CanCast(MIRROR_IMAGE) && FrostMageSettings.Instance.CDUseMirrorImage == FrostMageSettings.CDUseType.BOSS)
                    {
                        utils.LogActivity(MIRROR_IMAGE);
                        return utils.Cast(MIRROR_IMAGE);
                    }
      

                }
            }
            return false;
        }

        private bool PrismaticCrystal()
        {
            if (!FrostMageSettings.Instance.PrismaticCrystalOnlyOnBurst && talents.IsSelected(20) && !target.IsMoving && !Me.IsMoving && utils.CanCast(PRISMATIC_CRYSTAL)
                && (extra.IsTargetBoss() || utils.AllAttaccableEnemyMobsInRangeFromTarget(target, 8, ExtraUtilsSettings.Instance.provinGround_Targeting).Count() >= FrostMageSettings.Instance.PrismaticCrystalEnemiesNum))
            {
                if(utils.GetSpellCooldown(FROZEN_ORB).Milliseconds == 0 || utils.PlayerCountBuff(FINGER_OF_FROST) ==2 || utils.isAuraActive(BRAIN_FREEZE) )
                {
                    if (utils.CanCast(FROST_BOMB, target) && !utils.isMyAuraActive(FROST_BOMB, target) && nextTimeFrostBombAllowed < DateTime.Now
                        && target.Entry != 76933)
                    {
                        utils.LogActivity(FROST_BOMB, target.SafeName);
                        SetNextTimeFrostBomb();
                        return utils.Cast(FROST_BOMB, target);
                    }
                    else if (utils.GetSpellCooldown(FROZEN_ORB).Milliseconds == 0
                        && FrostMageSettings.Instance.AutoFrozerOrb && !Me.IsMoving && Me.IsSafelyFacing(target, 45)
                        && !FrostMageSettings.Instance.AvoidAOE)
                    {
                        utils.LogActivity(FROZEN_ORB, target.SafeName);
                        return utils.Cast(FROZEN_ORB, target);
                    }
                    else
                    {
                        utils.LogActivity(PRISMATIC_CRYSTAL, target.SafeName);
                        utils.Cast(PRISMATIC_CRYSTAL, target);
                        return SpellManager.ClickRemoteLocation(target.Location);
                    }
                }
            }
            return false;
        }
    }
}
